package me.zhujin.java.learnjava.myserver;

import me.zhujin.java.learnjava.myserver.enums.HttpMethod;
import me.zhujin.java.learnjava.myserver.util.DeCodeUtil;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.*;


/**
 * Created by zhujin on 10/20/16.
 * blog:www.zhujin.me
 * email: zhujin.nova@gmail.com
 */
public class MyRequest {

    //请求方式
    private HttpMethod method;
    //请求资源
    private String url;
    //请求
    private Map<String, List<String>> parameterMapValue;
    private List<String> paramsList;
    private InputStream in;
    private String requestInfo;
    private String paramString;

    public MyRequest() {
    }

    ;

    public MyRequest(Socket client) throws IOException {
        method = HttpMethod.DEFAULT;
        url = "";
        parameterMapValue = new HashMap<String, List<String>>();
        in = client.getInputStream();
        byte[] data = new byte[20480];
        int len = in.read(data);
//        in.close();
//        in.reset();


        if (len >0){
            try {
                requestInfo = new String(data, 0, len, Charset.defaultCharset());
            } catch (Exception e) {

                System.out.println(Arrays.toString(data));
                e.printStackTrace();

            }
            paramsList = new ArrayList<String>();
            parseRequestInfo();
        }
    }

    private void parseRequestInfo() {
        if (null == requestInfo || requestInfo.trim().isEmpty()) {
            return;
        }

//        GET / HTTP/1.1
//        Host: 192.168.0.131:8080
//        User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:47.0) Gecko/20100101 Firefox/47.0
//        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
//Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
//Accept-Encoding: gzip, deflate
//DNT: 1
//Connection: keep-alive
//Cache-Control: max-age=0

        /**
         *  请求方式.请求路径,请你去参数(get 存在)
         *  GET /xxxx
         *  如果为post方式在正文中.
         *
         */
        String firstLine = requestInfo.substring(0, requestInfo.indexOf(Const.CRLR));
        int idx = requestInfo.indexOf("/");
        this.method = HttpMethod.parseStr(firstLine.substring(0, idx).trim());
        String urlStr = firstLine.substring(idx, firstLine.indexOf("HTTP/"));
        if (this.method == HttpMethod.POST) {
            this.url = urlStr.trim();
            this.paramString = requestInfo.substring(requestInfo.lastIndexOf(Const.CRLR)).trim();
        } else if (this.method == HttpMethod.GET) {
            if (urlStr.contains("?")) {
                String[] urlArray = urlStr.split("\\?");
                this.url = urlArray[0].trim();
                this.paramString = urlArray[1].trim();
            } else {
                this.url = urlStr.trim();
//                String[] urlArray = urlStr.split("\\\\?");
//                this.url = urlArray[0].trim();
            }
        }
        //
        if (paramString == null || paramString.equals("")) {
            return;
        } else {
            parseParams(paramString);
        }
    }

    private void parseParams(String paramString) {
        StringTokenizer token = new StringTokenizer(paramString, "&");
        while (token.hasMoreTokens()) {
            String keyValue = token.nextToken();
            String[] ks = keyValue.split("=");
            if (1 == ks.length) {
                ks = Arrays.copyOf(ks, 2);
                ks[1] = null;
            }
            String key = ks[0];
            String value = ks[1];
            if (value != null && value.equals("null")) {
                value = null;
            }
            value = DeCodeUtil.decode(value, Charset.defaultCharset().name());
            if (parameterMapValue.containsKey(key)) {
                parameterMapValue.get(key).add(value);
            } else {
                parameterMapValue.put(key, new ArrayList<String>());
                parameterMapValue.get(key).add(value);
            }
            if (value != null) {
                paramsList.add(value);
                System.out.println(value);
            }
        }
    }


    public String[] getParmers(String name) {
        if (parameterMapValue.containsKey(name)) {
            String[] values;
            return parameterMapValue.get(name).toArray(new String[0]);
        } else {
            return null;
        }
    }


    public String getParmer(String name) {
        String[] values = getParmers(name);
        if (values == null) return null;
        return values[0];
    }

    public static void main(String[] args) throws IOException {
        String par = "u=1&c=2&a=null";
        new MyRequest().parseParams(par);
    }

    public String getUrl() {
        return url;
    }


    public List<String> getParamsList() {
        return paramsList;
    }


    public HttpMethod getMethod() {
        return method;
    }

    public void setMethod(HttpMethod method) {
        this.method = method;
    }
}
